<!DOCTYPE html>
<html>
<head>
	<title></title>
	<link rel="stylesheet" type="text/css" href="../公用CSS文件/all.css" />
	<script type="text/javascript" src="../js/jquery.min.js"></script> 	<script type="text/javascript" src="../js/js.js"></script>
	<meta charset="utf-8">
	<style type="text/css">
		table{min-width:80%}
	</style>
</head>
<body>
<div class="dt">架构走向总览</div>
<ul>
	<div class="ltable showimg">架构走向</div>
	<div class="img">
		<table>
			<tr>
				<th>核心文件</th><th>步骤</th><th>说明</th>
			</tr>
			<tr>
				<td>入口文件</td>
				<td>加载引导文件(start.php，依据版本有变动)，定义应用目录</td>
				<td>应用目录通常为application，入口文件不定义会在base常量定义为http请求脚本的目录</td>
			</tr>
			<tr>
				<td>框架启动文件（start.php）</td>
				<td>加载基础文件(base.php)->执行程序并响应</td>
				<td>基础base文件用来定义常量、加载loader、加载env变量、注冊自动加载、注册错误机制、 加载惯例配置</td>
			</tr>
			<tr>
				<td>应用初始化run</td>
				<td>初始化应用initCommon、模块绑定设置、语言加载、调度和监听、监听app_begin、请求缓存、执行调度到的程序、输出数据、监听app_end</td>
				<td></td>
			</tr>
			<tr>
				<td>APP->initCommon()</td>
				<td>注册命名空间、初始化init、调试设置、公共函数库、设置时区、监听app_init</td>
				<td>返回所有配置</td>
			</tr>
			<tr>
				<td>APP->init()</td>
				<td>加载初始化文件(自定义或加载模块配置、数据库配置、extra扩展配置、场景配置、行为扩展配置(钩子)、公共文件、语言包)</td>
				<td>返回所有配置(中间有加载配置已经不同)</td>
			</tr>
		</table>
		<li>加载route配置</li>
	</div>
</ul>

<div class="dt">ThinkPHP5配置</div>
<ul>
	<div class="ltable showimg">配置目录</div>
	<div class="img">
		<table>
			<tr>
				<th>配置类型</th>
				<th>说明</th>
			</tr>
			<tr>
				<td>惯例配置</td>
				<td>tp框架下的convention文件</td>
			</tr>
			<tr>
				<td>应用配置</td>
				<td>默认为应用目录</td>
			</tr>
			<tr>
				<td>模块配置</td>
				<td>模块目录</td>
			</tr>
			<tr>
				<td>扩展配置</td>
				<td>模块目录或应用目录下的extra目录</td>
			</tr>
			<tr>
				<td>场景配置</td>
				<td>依据app_status的值加载模块和应用下的同名文件(在应用状态配置加载步骤中完成)</td>
			</tr>
			<tr>
				<td>动态配置</td>
				<td>在调度到的处理程序中的配置</td>
			</tr>
		</table>
		<li>配置的优先级是：动态配置 > 场景配置 模块扩展配置 > 模块配置 > 应用扩展配置 > 应用配置 > 惯例配置 </li>
		<li>应用配置的目录是由常量CONF_PATH决定，该常量可以在应用初始化前预先定义</li>
	</div>

	<div class="ltable showimg">配置文件</div>
	<div class="img">
		<table>
			<tr>
				<th>文件</th><th>说明</th>
			</tr>
			<tr>
				<td>database</td>
				<td>数据库配置文件</td>
			</tr>
			<tr>
				<td>config</td>
				<td>配置文件</td>
			</tr>
			<tr>
				<td>route</td>
				<td>路由配置文件</td>
			</tr>
		</table>
		<li>配置文件默认return一个数组，也支持xml、json、ini格式，database和route为常用的独立配置，会覆盖config的同名配置，其中框架核心不会使用config文件的路由配置</li>
	</div>

	<div class="ltable showimg">配置Config类</div>
	<div class="img">
		<table>
			<tr>
				<th>方法</th><th>作用</th><th>参数</th><th>返回值</th>
			</tr>
			<tr>
				<td>get</td>
				<td>获取配置，如果是二级且未找到会去重载当前模块扩展配置</td>
				<td>str配置 【range作用域】</td>
				<td>一般为字符串、数组、布尔值</td>
			</tr>
			<tr>
				<td>set</td>
				<td>动态设置配置，支持options参数批量设置</td>
				<td>str键 mix值 【range作用域】</td>
				<td>单独返回配置值，批量返回配置数组</td>
			</tr>
			<tr>
				<td>range</td>
				<td>设置当前配置作用域</td>
				<td>str作用域</td>
				<td>无返回值</td>
			</tr>
			<tr>
				<td>parse</td>
				<td>调用think\config\driver下的解析类解析配置文件并更新配置</td>
				<td>路径 type类型【str配置名 range作用域】</td>
				<td>返回解析文件后调用set的结果</td>
			</tr>
			<tr>
				<td>load</td>
				<td>解析读取配置，无法解析调用parse解析</td>
				<td>file路径 【name文件名=''  range=''】</td>
				<td>正常返回调用set的结果</td>
			</tr>
			<tr>
				<td>has</td>
				<td>检查配置是否存在</td>
				<td>配置名</td>
				<td>布尔值</td>
			</tr>
			<tr>
				<td>reset</td>
				<td>重置配置</td>
				<td>range作用域=''</td>
				<td>无返回值</td>
			</tr>
		</table>
		<li>Config类的所有成员都是static成员，内置config属性存储加载和设置的配置，range存储当前作用域，所有操作默认在当前range进行，range默认为空，除非自己设置框架不会操作range</li>
		<li>Config类支持二级配置，database.username为数据库database下的username配置，parse、load方法的name参数设置会将整个配置设为name下的二级配置</li>
	</div>

	<div class="ltable showimg">环境变量</div>
	<div class="img">
		<li>在开发过程中，可以在应用根目录下面的.env来模拟环境变量配置，.env文件中的配置参数定义格式采用ini方式，并使用Env::get('name',default=null)获取环境变量</li>
		<li>环境变量支持ini模式[database]的二级配置，获取时可以使用config类似的语法，且"."还可以更换为"_"</li>
	</div>
</ul>

<div class="dt">ThinkPHP5路由</div>
<ul>
	<div class="ltable showimg">路由模式</div>
	<div class="img">
		<table>
			<tr>
				<th>模式</th><th>说明</th><th>配置</th>
			</tr>
			<tr>
				<td>普通pathinfo</td>
				<td>默认模式：模块/控制器/操作(需要apache和nginx允许)</td>
				<td>无需配置默认开启</td>
			</tr>
			<tr>
				<td>混合模式</td>
				<td>默认的pathinfo+自定义的路由</td>
				<td>开启url_route_on，关闭url_route_must</td>
			</tr>
			<tr>
				<td>强制模式</td>
				<td>所有路由都必须注册</td>
				<td>开启url_route_on，开启url_route_must</td>
			</tr>
		</table>
	</div>

	<div class="ltable showimg">特殊路由</div>
	<div class="img">
		<table>
			<tr>
				<th>路由类型</th><th>说明</th><th>注册方式</th>
			</tr>
			<tr>
				<td>rest路由</td>
				<td>注册一整套restfull路由，包含index、create、save、read、edit、update、delete</td>
				<td>配置注册为__rest__，方法注册为resource方法</td>
			</tr>
			<tr>
				<td>miss路由</td>
				<td>在没有匹配到所有的路由规则后执行一条设定的路由</td>
				<td>配置注册为__miss__，方法注册为miss方法</td>
			</tr>
			<tr>
				<td>domain路由</td>
				<td>为指定的域名绑定路由，需要开启url_domain_deploy</td>
				<td>配置注册为__domain__，方法注册为domain</td>
			</tr>
		</table>
		<li>rest路由除了save为post、delete为delete、update为put之外，都是get请求，restfull资源路由对应的地址和请求方式也可以使用rest方法更改规则</li>
		<li>miss路由在很多版本中有BUG，但实际开发基本不会使用</li>
		<li>domain路由的域名可以为子域名前缀、全域名、ip，且支持使用通配符，通配符字符能传递给路由地址中的通配符</li>
		<li>如果域名路由后缀包含多个常用的域名后缀，如com.cn，则需要配置类似'url_domain_root'=>'thinkphp.com.cn'</li>
	</div>

	<div class="ltable showimg">Url类和url生成</div>
	<div class="img">
		<table>
			<tr>
				<th>方法</th><th>作用</th><th>参数</th><th>返回值</th>
			</tr>
			<tr>
				<td>build</td>
				<td>生成url，支持路由反射</td>
				<td>url='' 【vars变量=[] 后缀='' domain域名=false】</td>
				<td>字符串路由</td>
			</tr>
			<tr>
				<td>getRuleUr</td>
				<td>从规则中解析域名等数据，会将url中的组合变量替换为变量的值</td>
				<td>rule 【&vars=[]】</td>
				<td>包含url、domain、suffix的数组或false</td>
			</tr>
			<tr>
				<td>root</td>
				<td>指定当前生成url的入口文件</td>
				<td>str相对网站目录的文件地址</td>
				<td>无</td>
			</tr>
			<tr>
				<td>parseUrl</td>
				<td>转换路由，实际上相当于计算反射后的路由</td>
				<td>url路由  【&$domain】</td>
				<td>返回解析后的url</td>
			</tr>
			<tr>
				<td>parseDomain</td>
				<td>解析domain，可能来自请求地址、域名绑定对应的路由反射、传入的domain</td>
				<td>&url路由 doamin域名</td>
				<td>带协议的完整域名</td>
			</tr>
			<tr>
				<td>parseSuffix</td>
				<td>解析url后缀，可能来自传入的后缀、配置的后缀</td>
				<td>str后缀</td>
				<td>经过处理的".文件类型"的后缀</td>
			</tr>
		</table>
		<li>route类全是静态成员，除了root、getRuleUrl、build之外都是protected权限。内置root属性存储当前入口设置，bindCheck存储parseUrl解析路由反射是时否有路由绑定</li>
		<li>build方法的大致流程是：解析路由标识、解析url分段识别domain、query、锚点、参数转数组、路由标识解析(getRuleUrl)、别名解析、解析域名绑定反射、还原分隔符后缀锚点、参数组装、检测域名(parseDomain)、组装域名</li>
		<li>除了build方法，thinkphp5还提供了助手函数url，该函数实际上是间接调用url::build方法</li>
	</div>

	<div class="ltable showimg">Route路由注册</div>
	<div class="img">
		<table>
			<tr>
				<th>注册方法</th><th>作用</th><th>参数</th><th>返回值</th>
			</tr>
			<tr>
				<td>rule</td>
				<td>核心注册方法，注册路由，大多数其他方法都是间接调用此方法</td>
				<td>rule路由规则 route路由地址 【type="*" option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>group</td>
				<td>注册一组有共同路由规则不同变量或参数规则的路由</td>
				<td>rule路由规则 route路由地址 【option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>get</td>
				<td>注册get路由</td>
				<td>rule路由规则 route路由地址 【option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>post</td>
				<td>注册post路由</td>
				<td>rule路由规则 route路由地址 【option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>put</td>
				<td>注册put路由</td>
				<td>rule路由规则 route路由地址 【option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>delete</td>
				<td>注册delete路由</td>
				<td>rule路由规则 【route路由地址 option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>patch</td>
				<td>注册patch路由</td>
				<td>rule路由规则 【route路由地址 option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>any</td>
				<td>注册任意请求方式的路由</td>
				<td>rule路由规则 【route路由地址 option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>resource</td>
				<td>注册资源路由</td>
				<td>rule路由规则 【route路由地址 option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>controller</td>
				<td>注册控制器路由(官方文档称为快捷路由)</td>
				<td>rule路由规则 【route路由地址 option路由参数  pattern路由规则】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>alias</td>
				<td>注册路由地址的别名路由(rule为route的别名)</td>
				<td>【rule路由规则 route路由地址 option路由参数】</td>
				<td>无</td>
			</tr>
			<tr>
				<td>bind</td>
				<td>为当前请求绑定一个路由地址，一般在入口文件操作</td>
				<td>路由地址 【type类型=module】</td>
			</tr>
		</table>
		<li>路由注册都能options数组传参，都不返回数据，也都支持闭包函数。使用闭包指定路由地址时，路由地址中的动态变量(:name等) 会传入闭包函数同名变量</li>
		<li>控制器路由必须定位到控制器，控制器方法必须为规范的http请求方式method+action(路由到的方法)组成，以method方式请求action，才能路由到方法</li>
		<li>bind方法支持绑定到class、module模块/控制器/操作、namespace，绑定到命名空间namespace会将pathinfo第一段视为类其他视为参数，除此之外，还可以定义常量BIND_MODULE绑定到模块、开启auto_bind_module自动将项目目录下的入口文件绑定到同名模块</li>
	</div>

	<div class="ltable showimg">路由规则</div>
	<div class="img">
		<li>路由规则分为静态地址路由和动态地址路由，静态地址指明pathinfo路径，动态地址指明param参数，可以用'/'指明全路径匹配，也可以尾部追加$表示整个路由参数完全匹配规则</li>
	</div>

	<div class="ltable showimg">路由地址</div>
	<div class="img">
		<table>
			<tr>
				<th>类型</th><th>语法</th><th>说明</th>
			</tr>
			<tr>
				<td>pathinfo模块/控制器/操作</td>
				<td>【模块/控制器/操作】【?query参数】</td>
				<td>执行上会依照默认的调度程序依次执行</td>
			</tr>
			<tr>
				<td>重定向</td>
				<td>含http或路由地址以"/"开头【?query参数】</td>
				<td>执行301跳转</td>
			</tr>
			<tr>
				<td>控制器方法</td>
				<td>@【模块/控制器/】操作</td>
				<td>直接调用控制器的方法，不解析pathinfo、初始化模块</td>
			</tr>
			<tr>
				<td>类方法</td>
				<td>\namespace\class::静态方法或者\namespace\class@动态方法</td>
				<td>直接调用类方法</td>
			</tr>
			<tr>
				<td>路由到闭包函数</td>
				<td>以闭包函数指定路由</td>
				<td>当前response的param参数会传入闭包函数</td>
			</tr>
		</table>
		<li>5.0.4后，控制器方法、类方法的路由地址也支持response参数解析</li>
	</div>

	<div class="ltable showimg">路由参数</div>
	<div class="img">
		<table>
			<tr>
				<th>参数</th>
				<td>说明</td>
			</tr>
			<tr>
				<td>method</td>
				<td>http请求类型，支持多个</td>
			</tr>
			<tr>
				<td>ext</td>
				<td>url后缀html、htm，支持多个</td>
			</tr>
			<tr>
				<td>deny_ext</td>
				<td>url后缀反匹配，支持多选</td>
			</tr>
			<tr>
				<td>https</td>
				<td>检测是否是https，布尔值</td>
			</tr>
			<tr>
				<td>domain</td>
				<td>域名检测，支持全域名(不含协议)和子域名名称</td>
			</tr>
			<tr>
				<td>before_behavior</td>
				<td>前置行为检测</td>
			</tr>
			<tr>
				<td>after_behavior</td>
				<td>后置行为检测</td>
			</tr>
			<tr>
				<td>callback</td>
				<td>回调函数检测</td>
			</tr>
			<tr>
				<td>merge_extra_vars</td>
				<td>合并额外参数，组合完全匹配使用。如果有多个符合tp5规则的额外参数将原本匹配规则的多个参数识别为一个</td>
			</tr>
			<tr>
				<td>bind_model</td>
				<td>绑定模型(5.0.1)</td>
			</tr>
			<tr>
				<td>cache</td>
				<td>请求缓存，会缓存当前请求，请求有缓存时，直接调度纯静态页面(5.0.1)</td>
			</tr>
			<tr>
				<td>ajax</td>
				<td>检测是否是ajax请求(5.0.2)</td>
			</tr>
			<tr>
				<td>pjax</td>
				<td>检测是否是pjax请求(5.0.2)</td>
			</tr>
			<tr>
				<td>param_depr</td>
				<td>指定路由地址参数的分隔符(5.0.2)</td>
			</tr>
		</table>
		<li>行为检测使用钩子函数Hook::exec执行，结果为false则不匹配当前路由，callback同理，且在检测时都不会传入参数</li>
		<li>bind_model绑定模型的值为数组，key为属性名，其值为[模型，变量&变量]，设置之后会将参数和request传递的同名变量值传入模型作为where条件find一条数据并存储到request->key中，模型绑定也支持闭包，request传递的所有param参数会传入闭包函数</li>
		<li>pjax是在ajax请求返回部分html代码，然后渲染到页面上</li>
	</div>

	<div class="ltable showimg">变量规则</div>
	<div class="img">
		<table>
			<tr>
				<th>类型</th><th>说明</th>
			</tr>
			<tr>
				<td>局部变量规则</td>
				<td>作用在指定路由规则的变量规则，一般在路由规则中以:name指出，在pattern参数中设置规则</td>
			</tr>
			<tr>
				<td>全局变量规则</td>
				<td>作用在所有路由规则的变量规则，一般使用pattern注册</td>
			</tr>
			<tr>
				<td>完整url规则</td>
				<td>特殊的一种全局规则，标识为__url__，使用正则匹配整个url</td>
			</tr>
		</table>
		<li>所有变量规则都保存在Route类的rules静态属性数组的pattern中，也都最终使用pattern方法注册</li>
	</div>
</ul>


</body>
</html>
<!-- php think queue:work --queue TimedTasksQueue --daemon -->